package com.gaga.console.core.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gaga.common.constant.Constants;
import com.gaga.common.enums.DelFlag;
import com.gaga.common.enums.MenuTypeEnum;
import com.gaga.common.tree.ForestNodeMerger;
import com.gaga.console.base.entity.PageParams;
import com.gaga.console.base.mybatisplus.LambdaQueryWrapperExt;
import com.gaga.console.base.service.impl.SuperServiceImpl;
import com.gaga.console.core.entity.MenuMeta;
import com.gaga.console.core.entity.SysMenu;
import com.gaga.console.core.entity.vo.SysMenuVo;
import com.gaga.console.core.mapper.SysMenuMapper;
import com.gaga.console.core.service.SysMenuService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author liujia
 * @since 2022-07-14
 */
@Service
public class SysMenuServiceImpl extends SuperServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    public static final String HIDE_MENU = "1";

    @Override
    public List<SysMenuVo> routes() {

        List<String> roleList = StpUtil.getRoleList();
        //1. 获取用户的菜单列表，待扩展
        List<SysMenu> menus = this.baseMapper.routes(roleList.get(0));

        LambdaQueryWrapperExt<SysMenu> wraps = new LambdaQueryWrapperExt<>();
        wraps.eq(SysMenu::getDelFlag, DelFlag.OK.getCode());
        List<SysMenu> allMenuList = this.baseMapper.selectList(wraps);
        List<SysMenu> allParentSysMenuList = new ArrayList<>();
        menus.forEach(sysMenu -> getAllParent(allMenuList, allParentSysMenuList, sysMenu.getParentId()));
        menus.addAll(allParentSysMenuList);
        //2. 生成菜单树
        return ForestNodeMerger.merge(buildTree(menus));
    }

    /**
     * 暂时不再使用
     *
     * @param allMenuList
     * @param allParentSysMenuList
     * @param menuId
     */
    private void getAllParent(List<SysMenu> allMenuList, List<SysMenu> allParentSysMenuList, Long menuId) {
        Optional<SysMenu> first = allMenuList.stream().filter(sysMenu -> sysMenu.getId().equals(menuId)).findFirst();
        if (first.isPresent()) {
            SysMenu sysMenu = first.get();
            if (sysMenu.getId() != null && sysMenu.getId() != Constants.MENU_ROOT_ID.longValue()) {

                Optional<SysMenu> hasContain = allParentSysMenuList.stream().filter(sysMenu1 -> sysMenu1.getId().equals(sysMenu.getId())).findFirst();
                if (!hasContain.isPresent()) {
                    allParentSysMenuList.add(sysMenu);
                    getAllParent(allMenuList, allParentSysMenuList, sysMenu.getParentId());
                }
            }
        }
    }

    @Override
    public boolean checkChild(Long id) {
        return this.getMenuChild(id) > 0L ? Boolean.TRUE : Boolean.FALSE;
    }

    @Override
    public Long getMenuChild(Long menuId) {
        return this.baseMapper.selectCount(new LambdaQueryWrapper<SysMenu>().select(SysMenu::getId).eq(SysMenu::getDelFlag, DelFlag.OK.getCode()).eq(SysMenu::getParentId, menuId));
    }

    @Override
    public List<SysMenuVo> searchList(PageParams<SysMenu> data) {
        LambdaQueryWrapperExt<SysMenu> wraps = new LambdaQueryWrapperExt<>();
        wraps.eq(SysMenu::getDelFlag, DelFlag.OK.getCode()).orderByAsc(SysMenu::getSeqNo);
        data.buildSpecWrap(wraps, SysMenu.class);
        return this.buildTree(this.baseMapper.selectList(wraps));
    }

    /**
     * 对象转树节点
     *
     * @param sysMenus 系统菜单
     * @return List
     */
    public List<SysMenuVo> buildTree(List<SysMenu> sysMenus) {
        List<SysMenuVo> trees = new ArrayList<>();
        sysMenus.forEach(sysMenu -> {
            SysMenuVo tree = new SysMenuVo();
            BeanUtils.copyProperties(sysMenu, tree);
            MenuMeta meta = new MenuMeta();
            meta.setIcon(sysMenu.getIcon());
            meta.setTitle(sysMenu.getName());
            meta.setHideMenu(HIDE_MENU.equals(sysMenu.getHidden()));
            meta.setIgnoreKeepAlive(!sysMenu.getKeepAlive().equals("1"));
            // 只有当菜单类型为目录的时候，如果是顶级，则强制修改为Layout
            if (sysMenu.getParentId() == Constants.MENU_ROOT_ID.longValue() && MenuTypeEnum.DIR.getCode().equals(sysMenu.getType())) {
                tree.setComponent("Layout");
                tree.setRedirect("noRedirect");
                tree.setAlwaysShow(true);
            }
            tree.setMeta(meta);
            tree.setCreateTime(sysMenu.getCreateTime());
            if (MenuTypeEnum.DIR.getCode().equals(sysMenu.getType())) {
                tree.setTypeName(MenuTypeEnum.DIR.getMessage());
            } else if (MenuTypeEnum.MENU.getCode().equals(sysMenu.getType())) {
                tree.setTypeName(MenuTypeEnum.MENU.getMessage());
            } else if (MenuTypeEnum.BUTTON.getCode().equals(sysMenu.getType())) {
                tree.setTypeName(MenuTypeEnum.BUTTON.getMessage());
            }
            trees.add(tree);
        });
        return trees;
    }
}
